<?php

namespace app\api\model;

use app\common\model\Setting as SettingModel;
use think\Cache;
use app\common\library\wechat\WxUser;
use app\common\exception\BaseException;
use app\common\model\User as UserModel;
use app\api\model\dealer\Referee as RefereeModel;
use app\api\model\dealer\Setting as DealerSettingModel;
use app\common\library\wechat\crypt\wxBizDataCrypt;

/**
 * 用户模型类
 * Class User
 * @package app\api\model
 */
class User extends UserModel
{
    private $token;

    private $is_bind;//是否绑定手机号

    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
        'wxapp_id',
    ];

    /**
     * 获取用户信息
     * @param $token
     * @return null|static
     * @throws \think\exception\DbException
     */
    public static function getUser($token)
    {
        return self::detail(['open_id' => Cache::get($token)['openid']]);
    }

    /**
     * 用户登录
     * @param array $post
     * @return string
     * @throws BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
    public function login($post)
    {
        // 微信登录 获取session_key
        $session = $this->wxlogin($post['code']);
        // 自动注册用户
        $referee_id = isset($post['referee_id']) ? $post['referee_id'] : null;
        $userInfo = json_decode(htmlspecialchars_decode($post['user_info']), true);
        $userModel = $this->register($session['openid'], $userInfo, $referee_id);
        //判断是否绑定手机号 1 为绑定 2 为没有绑定
        $this->is_bind = !empty($userModel['mobile']) ? 1 : 2;
        // 生成token (session3rd)
        $this->token = $this->token($session['openid']);
        // 记录缓存, 7天
//        Cache::set($this->token, $session, 86400 * 7);
        Cache::set($this->token, $session);
        return $userModel['user_id'];
    }

    /**
     * 获取手机号绑定状态
     * @return mixed
     */
    public function getBind()
    {
        return $this->is_bind;
    }

    /**
     * 获取token
     * @return mixed
     */
    public function getToken()
    {
        return $this->token;
    }

    /**
     * 获取token
     * @param $post
     * @return string
     * @throws BaseException
     * @throws \think\exception\DbException
     */
    public function getUserToken($post)
    {
        $session = $this->wxlogin($post['code']);
        $userModel = self::get(['open_id' => $session['openid'], 'is_delete' => 0]);
        if ($userModel) {
            $this->token = $this->token($session['openid']);
            $this->is_bind = !empty($userModel['mobile']) ? 1 : 2;
            Cache::set($this->token, $session);
            return $userModel['user_id'];
        }
        return '';
    }

    /**
     * 微信登录
     * @param $code
     * @return array|mixed
     * @throws BaseException
     * @throws \think\exception\DbException
     */
    private function wxlogin($code)
    {
        // 获取当前小程序信息
        $wxConfig = Wxapp::getWxappCache();
        // 微信登录 (获取session_key)
        $WxUser = new WxUser($wxConfig['app_id'], $wxConfig['app_secret']);
        if (!$session = $WxUser->sessionKey($code))
            throw new BaseException(['msg' => 'session_key 获取失败']);
        return $session;
    }

    /**
     * 生成用户认证的token
     * @param $openid
     * @return string
     */
    private function token($openid)
    {
        return md5($openid . self::$wxapp_id . 'token_salt');
    }

    /**
     * 自动注册用户
     * @param $open_id
     * @param $data
     * @param int $referee_id
     * @return mixed
     * @throws \Exception
     * @throws \think\exception\DbException
     */
    private function register($open_id, $data, $referee_id = null)
    {
        // 查询用户是否已存在
        $user = self::detail(['open_id' => $open_id]);
        $model = $user ?: $this;
        $data['open_id'] = $open_id;
        $data['wxapp_id'] = self::$wxapp_id;
        // 用户昵称
        $data['nickName'] = preg_replace('/[\xf0-\xf7].{3}/', '', $data['nickName']);
        try {
            $this->startTrans();
            // 保存/更新用户记录
            if (!$model->allowField(true)->save($data))
                throw new BaseException(['msg' => '用户注册失败']);
            //获取后台设置的积分
            $values = SettingModel::getItem("store");
            // 记录推荐人关系
            if (!$user && $referee_id > 0)
                RefereeModel::createRelation($model['user_id'], $referee_id);
            if (!$user) {
                //注册用户积分
                if ($values['user']['register_points'] > 0 && !empty($values['user']['register_points'])) {
                    //初始化points
                    $model['points'] = 0;
                    $model['total_points'] = 0;
                    //更改用户会员等级
                    $model->save(['grade_id' => 10001]);
                    $describe = "新用户注册";
                    $model->setIncPoints($values['user']['register_points'], $describe, $model['user_id'], 20, 20, 40);
                }
                //分享积分
                if ($values['user']['share_points'] > 0 && !empty($values['user']['share_points']) && $referee_id > 0) {
                    //给分享的分销商增加积分
                    $describe = "【".$model['nickName']."】"."新用户注册";
                    $userModel = self::detail($referee_id);
                    if ($userModel) {
                        $userModel->setIncPoints($values['user']['share_points'], $describe, $model['user_id'], 20, 10, 40);
                    }
                }
            }
            $this->commit();
        } catch (\Exception $e) {
            $this->rollback();
            throw new BaseException(['msg' => $e->getMessage()]);
        }
        return $model;
    }

    /**
     * 解密手机号
     * @param $postData
     * @return false|mixed
     * @throws BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
    public function bindUserMobile ($postData)
    {
        $session = Cache::get($postData['token']);
        $wxConfig = Wxapp::getWxappCache();
        //解码得到手机号
        $pc = new wxBizDataCrypt($wxConfig['app_id'], $session['session_key']);
        $errCode = $pc->decryptData($postData['encryptedData'], $postData['iv'], $data );
        if ($errCode == 0) {
            //解密成功
            //手机号$data['phoneNumber']
            $data = json_decode($data,true);
            $user = self::detail(['open_id' => $session['openid']]);
            $user->mobile = $data['phoneNumber'];
            $user->save();
            return true;
        } else {
            return false;
        }
    }

    /**
     * 提交备注
     * @param $user
     * @param $data
     * @return false|int
     * @throws BaseException
     */
    public function submit($user, $data)
    {
        // 数据验证
        $this->validation($data);
        //获取用户信息
        $userModel = self::detail($data['user_id']);
        // 新增申请记录
        $userModel->save(['remark' => $data['remark']]);
        return true;
    }

    /**
     * 数据验证
     * @param $data
     * @throws BaseException
     */
    private function validation($data)
    {
        if (empty($data['user_id']) || empty($data['user_id'])) {
            throw new BaseException(['msg' => '请选择用户']);
        }
        if (empty($data['remark']) || empty($data['remark'])) {
            throw new BaseException(['msg' => '请填写备注']);
        }
    }

}
